#include "FileUtil.h"
#include "StringUtil.h"
#include <iostream>
#ifdef CXX_LESS_17
#include <sys/stat.h>
#endif


std::string GetFilenameWithoutExtension(const std::string &path)
{
#ifndef CXX_LESS_17
        if (path.empty()) {
            return "" ;
        }
        return std::filesystem::path(path).stem().string();
#else
        // 获取文件名起始位置（最后一个 / 或 \ 之后）
        size_t slashPos = path.find_last_of("/\\");
        size_t start = (slashPos == std::string::npos) ? 0 : slashPos + 1;

        // 获取扩展名前的位置（最后一个点）
        size_t dotPos = path.find_last_of('.');

        // 点如果在文件名部分之外（例如在目录名中），忽略
        if (dotPos == std::string::npos || dotPos < start) {
            dotPos = path.length();
        }

        return path.substr(start, dotPos - start);
#endif
}

std::string GetExtension(const std::string &path)
{
#ifndef CXX_LESS_17
        return StringUtil::ToLowerCase(std::filesystem::path(path).extension().string());
#else
        // 找最后一个斜杠（表示路径分隔）
        size_t slashPos = path.find_last_of("/\\");
        size_t dotPos = path.find_last_of('.');

        // 点不存在或在路径前面，说明没有扩展名
        if (dotPos == std::string::npos || (slashPos != std::string::npos && dotPos < slashPos)) {
            return "";
        }

        return path.substr(dotPos);
#endif
}

bool IsFileExist(const std::string &path)
{
#ifndef CXX_LESS_17
        return std::filesystem::exists(path) && std::filesystem::is_regular_file(path);
#else 
        struct stat buffer;
        return (stat(path.c_str(), &buffer) == 0); // 如果返回0，路径存在
#endif
}

bool IsDirExist(const std::string &path)
{
#ifndef CXX_LESS_17
        return std::filesystem::exists(path) && std::filesystem::is_directory(path);
#else
        struct stat buffer;
        // 检查路径是否存在且是一个目录
        if (stat(path.c_str(), &buffer) == 0) {
            return S_ISDIR(buffer.st_mode);  // 判断是否是目录
        }
        return false;  // 如果路径不存在或不是目录
#endif
}

#ifndef CXX_LESS_17
void TraverseDirectory(const std::filesystem::path &path, std::vector<std::string> *containers)
{
    for (const auto &entry : std::filesystem::directory_iterator(path))
    {
        if (entry.is_directory())
        {
            TraverseDirectory(entry.path(), containers); // 递归遍历子目录
        }
        else
        {
            containers->emplace_back(entry.path().string());
        }
    }
}
#else
void TraverseDirectory(const std::string& path, std::vector<std::string> *containers)
{
   DIR* dir = opendir(path.c_str());
    if (dir == nullptr) {
        std::cerr << "Unable to open directory: " << path << std::endl;
        return;
    }

    struct dirent* entry;
    while ((entry = readdir(dir)) != nullptr) {
        // Skip hidden files (dotfiles)
        if (entry->d_name[0] != '.') {
            // Combine the directory path and file name
            std::string filePath = path + "/" + entry->d_name;

            // 获取绝对路径
            char absPath[PATH_MAX];
            if (realpath(filePath.c_str(), absPath)) {
                // std::cout << absPath << std::endl;

                // 如果是目录，递归遍历
                struct stat statbuf;
                if (stat(absPath, &statbuf) == 0 && S_ISDIR(statbuf.st_mode)) {
                    // 如果是目录，递归进入子目录
                    TraverseDirectory(absPath,containers);
                }else{
                    containers->emplace_back(absPath);
                }
            } else {
                std::cerr << "Error resolving absolute path for " << filePath << std::endl;
            }
        }
    }

    closedir(dir);
}
#endif

#ifdef CXX_LESS_17
bool RemoveDir(const std::string& path) {
    struct stat statbuf;
    if (stat(path.c_str(), &statbuf) != 0) {
        std::cerr << "Error getting status of file or directory: " << path << std::endl;
        return false;
    }

    if (S_ISDIR(statbuf.st_mode)) {
        // 如果是目录，递归删除目录内容
        DIR* dir = opendir(path.c_str());
        if (dir == nullptr) {
            std::cerr << "Unable to open directory: " << path << std::endl;
            return false;
        }

        struct dirent* entry;
        while ((entry = readdir(dir)) != nullptr) {
            // Skip hidden files (dotfiles)
            if (entry->d_name[0] != '.') {
                // 拼接完整路径
                std::string fullPath = path + "/" + entry->d_name;
                
                // 递归删除文件/子目录
                RemoveDir(fullPath);
            }
        }
        closedir(dir);

        // 删除目录
        if (rmdir(path.c_str()) != 0) {
            std::cerr << "Error deleting directory: " << path << std::endl;
            return false;
        }
    } else if (S_ISREG(statbuf.st_mode)) {
        // 如果是文件，直接删除
        if (remove(path.c_str()) != 0) {
            std::cerr << "Error deleting file: " << path << std::endl;
            return false;
        }
    } else {
        std::cerr << "Unknown file type: " << path << std::endl;
        return false;
    }

    return true;
}

void MakeDir(const std::string &path)
{
    if (mkdir(path.c_str(), S_IRWXU) == 0) {
        std::cout << "Directory created successfully!" << std::endl;
    } else {
        std::cerr << "Error creating directory: " << std::endl;
    }
}

#endif
